package com.yyw.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyw.common.constant.product.ProductAttrConstant;
import com.yyw.common.utils.PageUtils;
import com.yyw.common.utils.Query;
import com.yyw.gulimall.product.dao.AttrDao;
import com.yyw.gulimall.product.entity.*;
import com.yyw.gulimall.product.service.*;
import com.yyw.gulimall.product.vo.AttrCatelogPathVo;
import com.yyw.gulimall.product.vo.AttrVo;
import com.yyw.gulimall.product.vo.supVo.Attr;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("attrService")
@RequiredArgsConstructor
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    /**
     * 属性分组与属性关联接口
     */
    private final AttrAttrgroupRelationService attrAttrgroupRelationService;
    /**
     * 属性分组接口
     */
    @Autowired
    private AttrGroupService attrGroupService;
    /**
     * 分类接口
     */
    private final CategoryService categoryService;
    /**
     * 商品属性服务类
     */
    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryBaseListByType(Map<String, Object> params, long cateLogId, String type) {
        // 查询基础信息
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        if (cateLogId != 0) {
            wrapper.lambda().eq(AttrEntity::getCatelogId, cateLogId);
        }
        // 判断是否带参数查询
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and(e -> {
                e.lambda().eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
            });
        }
        // 如果是销售属性
        if (ProductAttrConstant.ATTR_REQUEST_TYPE_SALE.equalsIgnoreCase(type)) {
            wrapper.lambda().eq(AttrEntity::getAttrType, ProductAttrConstant.ATTR_TYPE_SALE);
        }
        // 查询结果
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params), wrapper
        );
        List<AttrEntity> list = page.getRecords();

        // 遍历结果，循环查询分组名称和分类名称
        List<AttrVo> voList = list.stream().map(e -> {
            AttrVo attrVo = new AttrVo();
            BeanUtils.copyProperties(e, attrVo);
            // 如果是销售属性则不查询分组信息
            if (!ProductAttrConstant.ATTR_REQUEST_TYPE_SALE.equalsIgnoreCase(type)) {
                // 通过关联表查询分组名称
                AttrAttrgroupRelationEntity attrAttrGroup = attrAttrgroupRelationService.getOne(
                        new QueryWrapper<AttrAttrgroupRelationEntity>().lambda()
                                .eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId()));
                if (null != attrAttrGroup && null != attrAttrGroup.getAttrGroupId()) {
                    AttrGroupEntity groupEntity = attrGroupService.getById(attrAttrGroup.getAttrGroupId());
                    attrVo.setGroupName(groupEntity.getAttrGroupName());
                }
            }
            // 查询分类名称
            CategoryEntity categoryEntity = categoryService.getById(attrVo.getCatelogId());
            attrVo.setCatelogName(categoryEntity.getName());
            return attrVo;
        }).collect(Collectors.toList());
        // 封装结果
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(voList);
        return pageUtils;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAttr(AttrVo attr) {
        // 保存自己
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.save(attrEntity);
        // 判断属性类型，是否要保存分组,基本属性才需要保存，销售属性不需要
        if (!ProductAttrConstant.ATTR_TYPE_SALE.equals(attr.getAttrType()) && !Objects.equals(null, attr.getAttrGroupId())) {
            // 保存属性分组关联
            AttrAttrgroupRelationEntity attrGroupEntity = new AttrAttrgroupRelationEntity();
            attrGroupEntity.setAttrGroupId(attr.getAttrGroupId());
            attrGroupEntity.setAttrId(attrEntity.getAttrId());
            attrGroupEntity.setAttrSort(0);
            attrAttrgroupRelationService.save(attrGroupEntity);
        }
    }

    @Override
    @Cacheable(value = "attrCatelogInfo", key = "'attrInfo-'+#root.args[0]")
    public AttrCatelogPathVo getByAttrCatelogPath(Long attrId) {
        // 查询自身信息
        AttrEntity entity = this.getById(attrId);
        // 查询三级分类的路径
        AttrCatelogPathVo pathVo = new AttrCatelogPathVo();
        BeanUtils.copyProperties(entity, pathVo);
        Long[] catelogPath = categoryService.findCatelogPath(entity.getCatelogId());
        pathVo.setCatelogPath(catelogPath);
        // 查询分组信息
        QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(AttrAttrgroupRelationEntity::getAttrId, attrId);
        AttrAttrgroupRelationEntity attrgroupRelationEntity = attrAttrgroupRelationService.getOne(queryWrapper);
        if (null != attrgroupRelationEntity) {
            pathVo.setAttrGroupId(attrgroupRelationEntity.getAttrGroupId());
        }
        return pathVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.updateById(attrEntity);

        // 判断属性类型，是否要保存分组,基本属性才需要保存，销售属性不需要
        if (!ProductAttrConstant.ATTR_TYPE_SALE.equals(attr.getAttrType())) {
            // 判断是否存在关联，否则就新增
            QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId());
            int count = attrAttrgroupRelationService.count(queryWrapper);
            if (count == 0) {
                // 新增
                AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity(null, attr.getAttrId(),
                        attr.getAttrGroupId(), 0);
                attrAttrgroupRelationService.save(relationEntity);
            } else {
                // 修改属性分组关联
                UpdateWrapper<AttrAttrgroupRelationEntity> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId())
                        .set(AttrAttrgroupRelationEntity::getAttrGroupId, attr.getAttrGroupId());
                attrAttrgroupRelationService.update(updateWrapper);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByIdCase(List<Long> asList) {
        // 收集要删除的关联ID
        List<Long> attrGropyId = new ArrayList<>();
        // 判断是否是销售属性，否则删除关联表
        asList.forEach(e -> {
            AttrEntity entity = this.getById(e);
            if (!entity.getAttrType().equals(ProductAttrConstant.ATTR_TYPE_SALE)) {
                QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(AttrAttrgroupRelationEntity::getAttrId, e);
                AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(queryWrapper);
                if (!Objects.equals(null, relationEntity)) {
                    attrGropyId.add(relationEntity.getId());
                }
            }
        });
        // 删除自己
        this.removeByIds(asList);
        // 删除关联关系
        if (!attrGropyId.isEmpty()) {
            attrAttrgroupRelationService.removeByIds(attrGropyId);
        }
    }

    @Override
    public PageUtils getNoAttrGroupRelation(Map<String, Object> params, long attrgroupId) {
        // 收集已经存在关联的属性列表
        List<Long> attrIds = null;
        // 1. 查询该分组所属的分类
        AttrGroupEntity groupEntity = attrGroupService.getById(attrgroupId);
        Long catelogId = groupEntity.getCatelogId();
        // 2. 查询该分类下的所有分组
        List<AttrGroupEntity> groups = attrGroupService.list(new QueryWrapper<AttrGroupEntity>()
                .lambda().eq(AttrGroupEntity::getCatelogId, catelogId));
        if (!CollectionUtils.isEmpty(groups)) {
            List<Long> groupIds = groups.stream().map(e -> e.getAttrGroupId()).collect(Collectors.toList());
            // 3. 查询分组所关联的属性
            List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationService
                    .list(new QueryWrapper<AttrAttrgroupRelationEntity>().lambda()
                            .in(AttrAttrgroupRelationEntity::getAttrGroupId, groupIds));
            if (!CollectionUtils.isEmpty(attrAttrgroupRelationEntities)) {
                attrIds = attrAttrgroupRelationEntities.stream().map(e -> e.getAttrId()).collect(Collectors.toList());
            }
        }

        // 4. 查询不属于这些分组的属性,并且属于当前分类下并且不是销售属性
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(AttrEntity::getCatelogId, catelogId).ne(AttrEntity::getAttrType, ProductAttrConstant.ATTR_TYPE_SALE);
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and(e -> {
                e.lambda().eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
            });
        }
        // 排除已关联的属性
        if (!CollectionUtils.isEmpty(attrIds)) {
            queryWrapper.lambda().notIn(AttrEntity::getAttrId, attrIds);
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), queryWrapper);
        return new PageUtils(page);

    }

    @Override
    public List<ProductAttrValueEntity> getSpuAttrById(Long spuId) {
        QueryWrapper<ProductAttrValueEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ProductAttrValueEntity::getSpuId, spuId);
        return productAttrValueService.list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Long spuId, List<Attr> attr) {
        //添加最新的属性
        if (!CollectionUtils.isEmpty(attr)) {
            // 删除原有的属性
            QueryWrapper<ProductAttrValueEntity> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(ProductAttrValueEntity::getSpuId, spuId);
            productAttrValueService.remove(wrapper);

            List<ProductAttrValueEntity> list = attr.stream().map(e -> {
                ProductAttrValueEntity attrValueEntity = ProductAttrValueEntity.builder()
                        .attrId(e.getAttrId())
                        .attrValue(e.getAttrValue())
                        .attrName(e.getAttrName())
                        .quickShow(e.getQuickShow())
                        .spuId(spuId)
                        .attrSort(0)
                        .build();
                return attrValueEntity;
            }).collect(Collectors.toList());
            productAttrValueService.saveBatch(list);
        }
    }

}